package com.highspeed.bdk.controller.physical;


import com.fasterxml.jackson.databind.util.JSONPObject;
import com.highspeed.bdk.MainApplication;
import com.highspeed.bdk.bean.entity.physical.Board;
import com.highspeed.bdk.bean.entity.physical.Cpu;
import com.highspeed.bdk.bean.entity.physical.MachineBox;
import com.highspeed.bdk.bean.entity.physical.PhysicalTopology;
import com.highspeed.bdk.service.physical.IPhysicalTopologyService;
import org.apache.struts2.json.JSONUtil;
import org.apache.struts2.json.annotations.JSON;
import org.hamcrest.Matchers;
import org.json.JSONObject;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.http.MediaType;
import org.springframework.security.test.context.support.WithMockUser;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
import org.springframework.test.web.servlet.MockMvc;
import org.springframework.test.web.servlet.ResultActions;
import org.springframework.test.web.servlet.request.MockHttpServletRequestBuilder;
import org.springframework.test.web.servlet.request.MockMvcRequestBuilders;
import org.springframework.test.web.servlet.result.MockMvcResultHandlers;
import org.springframework.test.web.servlet.result.MockMvcResultMatchers;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.LinkedMultiValueMap;

import static org.hamcrest.Matchers.hasSize;

@RunWith(SpringJUnit4ClassRunner.class)
@SpringBootTest(classes = {MainApplication.class})
@AutoConfigureMockMvc
@Transactional
@WithMockUser(username = "admin", roles = {"USER", "ADMIN", "abc"})
public class PhysicalTopologyControllerTester extends BaseDeviceServiceTester {
    @Autowired
    private MockMvc mvc;
    private PhysicalTopology physicalTopology;

    @Before
    public void init() {
        PhysicalTopology pt = createPhysicalTopology();

        for (int a = 0; a < 5; a++) {
            MachineBox mb = createMachineBox();
            for (int i = 0; i < 5; i++) {
                Board board = createBoard();

                for (int j = 0; j < 5; j++) {
                    Cpu cpu = createCpu();
                    board.getCpus().add(cpu);
                }
                mb.getBoards().add(board);
            }
            pt.getMachineBoxes().add(mb);
        }

        this.physicalTopology = physicalTopologyService.save(pt);
        for (MachineBox machineBox : this.physicalTopology.getMachineBoxes()) {
            for (Board board : machineBox.getBoards()) {
                createPhysicalLink(board.getCpus().get(0), board.getCpus().get(1));
            }
        }
        physicalTopologyService.flush();
        physicalTopologyService.getRepository().clear();
    }

    @Test
    public void save() throws Exception {
        PhysicalTopology p = new PhysicalTopology();
        p.setName("name");
        p.setCreator("creator");
        p.setNo("no");

        MachineBox machineBox = new MachineBox();
        machineBox.setMachineBoxName("machineBoxName");
        machineBox.setMachineBoxNo("machineBoxNo");
        machineBox.setRemark("remark");
        machineBox.setPhysicalTopology(p);
        p.getMachineBoxes().add(machineBox);
        for (int i = 0; i < 6; i++) {
            Board board = new Board();
            board.setBoardId("boardId");
            machineBox.getBoards().add(board);
            board.setMachineBox(machineBox);
        }
        for (int i = 0; i < 5; i++) {
            Cpu cpu = new Cpu();
            cpu.setCpuId("cpuId");
            machineBox.getBoards().get(0).getCpus().add(cpu);
            cpu.setBoard(machineBox.getBoards().get(0));
        }
        for (int i = 0; i < 5; i++) {
            Cpu cpu = new Cpu();
            cpu.setCpuId("cpuId");
            machineBox.getBoards().get(1).getCpus().add(cpu);
            cpu.setBoard(machineBox.getBoards().get(1));
        }
        for (int i = 0; i < 5; i++) {
            Cpu cpu = new Cpu();
            cpu.setCpuId("cpuId");
            machineBox.getBoards().get(2).getCpus().add(cpu);
            cpu.setBoard(machineBox.getBoards().get(2));
        }

        String str = JSONUtil.serialize(p);


        MockHttpServletRequestBuilder builder = MockMvcRequestBuilders.post("/physical_topology/save");
        //希望服务器返回的格式
        builder.accept(MediaType.APPLICATION_JSON_UTF8);
        //发送数据格式
        builder.contentType(MediaType.APPLICATION_JSON_UTF8);
        builder.content(str);

        ResultActions resultActions = this.mvc.perform(builder);

        resultActions.andExpect(MockMvcResultMatchers.status().isOk());
        resultActions.andExpect(MockMvcResultMatchers.content().contentType(MediaType.APPLICATION_JSON_UTF8));
        //打印信息
        resultActions.andDo(MockMvcResultHandlers.print());
        resultActions.andExpect(MockMvcResultMatchers.jsonPath("$.success", Matchers.is(true)));
        resultActions.andExpect(MockMvcResultMatchers.jsonPath("$.data.id").exists());
        resultActions.andExpect(MockMvcResultMatchers.jsonPath("$.data.machineBoxes[0].machineBoxName", Matchers.is("machineBoxName")));
        resultActions.andExpect(MockMvcResultMatchers.jsonPath("$.data.machineBoxes[0].boards[0].cpus[0].leftLinks").doesNotExist());
        resultActions.andExpect(MockMvcResultMatchers.jsonPath("$.data.machineBoxes[0].boards[0].cpus[0].rightLinks").doesNotExist());
    }

    @Test
    public void update() throws Exception {

        PhysicalTopology p = new PhysicalTopology();
        p.setId(physicalTopology.getId());
        p.setName("name");
        p.setCreator("creator");
        p.setNo("no");

        MachineBox machineBox = new MachineBox();
        machineBox.setMachineBoxName("machineBoxName");
        machineBox.setMachineBoxNo("machineBoxNo");
        machineBox.setRemark("remark");
        machineBox.setPhysicalTopology(p);
        p.getMachineBoxes().add(machineBox);
        for (int i = 0; i < 6; i++) {
            Board board = new Board();
            board.setBoardId("boardId");
            machineBox.getBoards().add(board);
            board.setMachineBox(machineBox);
        }
        for (int i = 0; i < 5; i++) {
            Cpu cpu = new Cpu();
            cpu.setCpuId("cpuId");
            machineBox.getBoards().get(0).getCpus().add(cpu);
            cpu.setBoard(machineBox.getBoards().get(0));
        }
        for (int i = 0; i < 5; i++) {
            Cpu cpu = new Cpu();
            cpu.setCpuId("cpuId");
            machineBox.getBoards().get(1).getCpus().add(cpu);
            cpu.setBoard(machineBox.getBoards().get(1));
        }
        for (int i = 0; i < 5; i++) {
            Cpu cpu = new Cpu();
            cpu.setCpuId("cpuId");
            machineBox.getBoards().get(2).getCpus().add(cpu);
            cpu.setBoard(machineBox.getBoards().get(2));
        }

        String str = JSONUtil.serialize(p, null, null, false, true);


        MockHttpServletRequestBuilder builder = MockMvcRequestBuilders.post("/physical_topology/save");
        //希望服务器返回的格式
        builder.accept(MediaType.APPLICATION_JSON_UTF8);
        //发送数据格式
        builder.contentType(MediaType.APPLICATION_JSON_UTF8);
        builder.content(str);

        ResultActions resultActions = this.mvc.perform(builder);

        resultActions.andExpect(MockMvcResultMatchers.status().isOk());
        resultActions.andExpect(MockMvcResultMatchers.content().contentType(MediaType.APPLICATION_JSON_UTF8));
        //打印信息
        resultActions.andDo(MockMvcResultHandlers.print());
        resultActions.andExpect(MockMvcResultMatchers.jsonPath("$.success", Matchers.is(true)));
        resultActions.andExpect(MockMvcResultMatchers.jsonPath("$.data.id").value(physicalTopology.getId()));
        resultActions.andExpect(MockMvcResultMatchers.jsonPath("$.data.machineBoxes[0].machineBoxName", Matchers.is("machineBoxName")));
        resultActions.andExpect(MockMvcResultMatchers.jsonPath("$.data.machineBoxes", Matchers.hasSize(1)));
        resultActions.andExpect(MockMvcResultMatchers.jsonPath("$.data.machineBoxes[0].boards", Matchers.hasSize(6)));
        resultActions.andExpect(MockMvcResultMatchers.jsonPath("$.data.machineBoxes[0].boards[0].cpus", Matchers.hasSize(5)));
        resultActions.andExpect(MockMvcResultMatchers.jsonPath("$.data.machineBoxes[0].boards[0].cpus[0].leftLinks").doesNotExist());
        resultActions.andExpect(MockMvcResultMatchers.jsonPath("$.data.machineBoxes[0].boards[0].cpus[0].rightLinks").doesNotExist());
        resultActions.andExpect(MockMvcResultMatchers.jsonPath("$.data.machineBoxes[1]").doesNotExist());
    }

    @Test
    public void queryVirtualLinksByPhysicalTopologyId() throws Exception {

        MockHttpServletRequestBuilder builder = MockMvcRequestBuilders.post("/physical_topology/get_virtual_links_by_physical_topology_id");
        builder.param("id", physicalTopology.getId() + "");
        builder.accept(MediaType.APPLICATION_JSON_UTF8);

        ResultActions resultActions = this.mvc.perform(builder);

        resultActions.andExpect(MockMvcResultMatchers.status().isOk());
        resultActions.andExpect(MockMvcResultMatchers.content().contentType(MediaType.APPLICATION_JSON_UTF8));
        //打印信息
        resultActions.andDo(MockMvcResultHandlers.print());
        resultActions.andExpect(MockMvcResultMatchers.jsonPath("$.success", Matchers.is(true)));
        resultActions.andExpect(MockMvcResultMatchers.jsonPath("$.data", Matchers.hasSize(25)));
    }

    @Test
    public void query() throws Exception {
        MockHttpServletRequestBuilder builder = MockMvcRequestBuilders.post("/physical_topology/query");
        builder.param("params.id_eq", physicalTopology.getId() + "");
        builder.accept(MediaType.APPLICATION_JSON_UTF8);

        ResultActions resultActions = this.mvc.perform(builder);

        resultActions.andExpect(MockMvcResultMatchers.status().isOk());
        resultActions.andExpect(MockMvcResultMatchers.content().contentType(MediaType.APPLICATION_JSON_UTF8));
        //打印信息
        resultActions.andDo(MockMvcResultHandlers.print());
        resultActions.andExpect(MockMvcResultMatchers.jsonPath("$.success", Matchers.is(true)));
        resultActions.andExpect(MockMvcResultMatchers.jsonPath("$.data", Matchers.hasSize(1)));
        resultActions.andExpect(MockMvcResultMatchers.jsonPath("$.data[0].machineBoxes", Matchers.hasSize(5)));
        resultActions.andExpect(MockMvcResultMatchers.jsonPath("$.data[0].machineBoxes[0].boards", Matchers.hasSize(5)));
        resultActions.andExpect(MockMvcResultMatchers.jsonPath("$.data[0].machineBoxes[0].boards[0].cpus", Matchers.hasSize(5)));
    }
}
